﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

#if !DESKTOP_TARGET
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework; //for Vector3 struct definition
#endif
using System.Windows.Threading;

namespace gamecontrol
{
    public partial class BoardControl : UserControl
    {


        //keyboard supporting for demo purposes
        InputBase input;
        ScreenRefreshRate refreshRate;
        Size containerSize;
        PhysicalBody ball;

        private int winCounter;
        private int lostCounter;

        private enum STATE
        {
            NOTSTARTED,
            RUNNING,
            PAUSED,
            SHUTDOWN
        };
        STATE state = STATE.NOTSTARTED;

        public BoardControl()
        {
            InitializeComponent();
            this.Loaded += handleOnLoad;
            this.SizeChanged += BoardControl_SizeChanged;
            refreshRate = new ScreenRefreshRate();
            ball = new PhysicalBody(ballCtrl, refreshRate, 4,
                new GameOverDelegate(GameOverFunction), new HitScoresDelegate(HitScoresFunction));
        }

        public void GameOverFunction()
        {
            lostCounter++;
            scores.Text = String.Format("Scores: You hit {0}, you lost {1}", winCounter, lostCounter);
            MessageBox.Show("You lost! Game Over :)");
            BoardControl_SizeChanged(null, null);
        }

        public void HitScoresFunction()
        {
            winCounter++;
            scores.Text = String.Format("Scores: You hit {0}, you lost {1}", winCounter, lostCounter); 
        }

        void BoardControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (input != null)
            {
                containerSize.Height = ((Grid)Parent).ActualHeight;
                containerSize.Width = ((Grid)Parent).ActualWidth;
                input.onSizeChanged(containerSize);
                ball.onSizeChanged(containerSize);
                setupWall();
            }
        }

        void handleOnLoad(object sender, RoutedEventArgs e)
        {
#if !DESKTOP_TARGET
            input = new InputAccelerometer(this.bouncer);
            BoardControl_SizeChanged(null, null); //wp7 specific
#else
            //input = new InputKeyboard(this.bouncer);
            input = new InputMouse(bouncer);
#endif

            input.handleOnLoaded(sender, e);
            //per frame animation support
            CompositionTarget.Rendering += gameLoopHandler;

            resumeLoop();
        }

        private void setupWall()
        {
            Brick brick = new Brick(boardRoot);
            
            double margin = brick.rootCanvas.Height / 2;

            int cols = (int)Math.Ceiling(containerSize.Width / (brick.rootCanvas.Width + margin)) - 1;
            int rows = 3;

            double offsetX = margin;
            double offsetY = margin * 2;

            brick.SetValue(Canvas.LeftProperty, offsetX);
            brick.SetValue(Canvas.TopProperty, offsetY);

            int colsPerRow = cols - 1;

            while (rows-- > 0)
            {
                while (colsPerRow-- > 0)
                {
                    brick = new Brick(boardRoot);
                    offsetX += (offsetX == 0) ? margin : margin + brick.rootCanvas.Width;
                    brick.SetValue(Canvas.LeftProperty, offsetX);
                    brick.SetValue(Canvas.TopProperty, offsetY);
                }
                offsetX = 0;
                offsetY += brick.rootCanvas.Height + margin;
                colsPerRow = cols;
            }
        }

        void gameLoopHandler(object sender, EventArgs e)
        {
            if (state != STATE.RUNNING)
                return;
            
            refreshRate.measure();
            input.handle();
            ball.updatePosition();
        }
        
        public void resumeLoop()
        {
            state = STATE.RUNNING;
        }

        public void pauseLoop()
        {
            state = STATE.PAUSED;
        }
    }
}
